--
-- Author: gnar
-- Date: 2016-01-15 17:23:40
--

local TextPaser = {}
local eventDispatcher = cc.Director:getInstance():getEventDispatcher()

TextPaser.separator = "#" --类型分隔 
TextPaser.subSeparator = "|" --类型分隔 

TextPaser.textSzie = 30
--这个前缀只是用于匹配和避免玩家误输入 并无加密效果  如果匹配不到 则全部远样输出
TextPaser.listenerNodePrefix = "lis" -- #lis@123/[金箍棒]/1/1/{1,1,{}}#(为了传最少的数据用于展示的界面不要做得需要太多的数据)
TextPaser.uiPrefix = "ui" --#ui@123/123#
TextPaser.facePrefix = "face" --#face@123/123#
TextPaser.wordPrefix = "word" --#word@123/1/啊啊啊啊啊#
TextPaser.listenerNodeStruct =
{
goodName = "",
color = Constants.color1,
listener = 0, --卡牌数据量太大 服务器会保存每个卡牌id 到时传id号 点击后会先请求服务器拿数据
args = {},
}
TextPaser.uiStruct =
{
idx = 0,
}
TextPaser.faceStruct =
{
idx = 0,
}
TextPaser.wordStruct =
{
color = Constants.color1,
text = "",
}

TextPaser.msgType = 
{
lis = 1,
ui = 2,
face = 3,
word = 4,
}

-- 玩家输入时 额外的数据只是对可点击的补充 实际上额外的数据只是对input的匹配 如果名字符合就会在encodeMsg中替换匹配值

--这样的话其实没必要像梦幻一样限制只能发一个可点击物品了 只需要限制encodeMsg的字符串长度 当个encodeMsg>200 或inputMsg>100时 提示内容太长

--[金箍棒]#51我什么都没说  data={ "[金箍棒]"= #lis@123/[金箍棒]/1/1/{1}#, ["#5#"] = "#face@123/5#“ }
function TextPaser.inputText2EncodeMsg(inputText, data) --返回label 
      
      for inputStr, encodeMsgStr in pairs(data) do  --inputStr 中特殊字符要用%转义
            inputText = string.gsub(inputText,inputStr,encodeMsgStr)
      end

      return inputText
end

function TextPaser.attachSrcForMsg(msg, channelIdx, senderName)
      
      local channelEncodeMsg = TextPaser.uiPrefix .. TextPaser.subSeparator .. channelIdx .. TextPaser.separator
      local senderEncodeMsg = ""
      if senderName then
            senderEncodeMsg = TextPaser.wordPrefix .. TextPaser.subSeparator .. 18 .. 
            TextPaser.subSeparator .. "[" .. senderName .. "]:" .. TextPaser.separator
      end

      return channelEncodeMsg .. senderEncodeMsg .. msg

end
-- "#ui@123/1##word@123/1/啊啊啊ssssssss啊啊##lis@123/[金箍棒]/1/1/{1}##face@123/2##word@123/1/啊啊啊啊啊#aaaaaawww"
function TextPaser.encodeMsg2RichText(encodeMsg, width, isForHeight, space, textSize) --返回richText

      space = space or 1
      textSize = textSize or TextPaser.textSzie

      local richText = ccui.RichText:create()
      richText:ignoreContentAdaptWithSize(false)
      richText:setUnifySizeEnabled(true)
      richText:setContentSize(cc.size(width, 0))
      richText:setVerticalSpace(space)

      local result = _splitEncodeMsg(encodeMsg)
      for i, v in ipairs(result) do
            local element
            if v.type == TextPaser.msgType.lis then
                  local goodName = v.struct.goodName
                  local color = v.struct.color
                  local listener = v.struct.listener
                  local args = v.struct.args

                  local label = cc.LabelTTF:create(goodName, Constants.font1, textSize)
                  label:setFontFillColor(color)
                  if not isForHeight then
                        local function onTouchBegan(touch, event)
                            local locationInNode = label:convertToNodeSpace(touch:getLocation())
                            local s = label:getContentSize()
                            local rect = cc.rect(0, 0, s.width, s.height)
                            if cc.rectContainsPoint(rect, locationInNode) then
                                return true
                            end
                            return false
                        end
                        local function onTouchEnded(touch, event)
                              listener(args)
                        end
                        local function onTouchMoved(touch, event)
                        end
                        local l = cc.EventListenerTouchOneByOne:create()
                        l:setSwallowTouches(true)
                        l:registerScriptHandler(onTouchBegan,cc.Handler.EVENT_TOUCH_BEGAN )
                        l:registerScriptHandler(onTouchEnded,cc.Handler.EVENT_TOUCH_ENDED )
                        l:registerScriptHandler(onTouchMoved, cc.Handler.EVENT_TOUCH_MOVED)
                        eventDispatcher:addEventListenerWithFixedPriority(l,Constants.chatTextPriority)
                        --eventDispatcher:addEventListenerWithSceneGraphPriority(l, label)
                  end

                  element = ccui.RichElementCustomNode:create(i, cc.c3b(255, 255, 255), 255, label)
            elseif v.type == TextPaser.msgType.ui then
                  local framePrefix = "t_icon_" .. v.struct.idx .. "_"
                  local animation = ManagerRes.getAniByFramePrefix(framePrefix)
                  animation:setDelayPerUnit(0.5)
                  local action = cc.Animate:create(animation)
                  local node = display.newSprite("#" .. framePrefix .. "1.png")
                  node:runAction(cc.RepeatForever:create(action))
                  element = ccui.RichElementCustomNode:create(i, cc.c3b(255, 255, 255), 255, node)
            elseif v.type == TextPaser.msgType.face then
                  local framePrefix = "emot_" .. v.struct.idx .. "_"
                  local animation = ManagerRes.getAniByFramePrefix(framePrefix)
                  animation:setDelayPerUnit(0.5)
                  local action = cc.Animate:create(animation)
                  local node = display.newSprite("#" .. framePrefix .. "1.png")
                  node:runAction(cc.RepeatForever:create(action))
                  element = ccui.RichElementCustomNode:create(i, cc.c3b(255, 255, 255), 255, node)
            elseif v.type == TextPaser.msgType.word then   
                  element = ccui.RichElementText:create(i, v.struct.color, 255, v.struct.text, Constants.font1, textSize)
            end
            richText:pushBackElement(element)
      end

      return richText
end

function TextPaser.listener0()

     Tips.ShowTTF({str = "这是一个宝贝！\n(展示界面)",color = Constants.color17})

end


_splitEncodeMsg = function(encodeMsg)
      local result = {}
      local strings = string.split(encodeMsg, TextPaser.separator)
      for _,v in pairs(strings) do
            local r = {}
            local s = string.split(v, TextPaser.subSeparator)
            if s[1] == TextPaser.listenerNodePrefix then --and s[2] and s[3] and s[4] and s[5] then
                  r.type = TextPaser.msgType.lis
                  local struct = {}
                  struct.goodName = s[2] or ""
                  local colorIdx = s[3] or 17
                  struct.color = Constants["color" .. colorIdx] or Constants.color1
                  local listenerIdx = s[4] or 0
                  struct.listener = TextPaser["listener" .. listenerIdx] or TextPaser.listener0
                  s[5] = s[5] or ""
                  struct.args = loadstring("return "..s[5])()--这个检测不了了 只能每个函数单独做下检测
                  r.struct = struct 
            elseif s[1] == TextPaser.uiPrefix and s[2] then
                  r.type = TextPaser.msgType.ui
                  local struct = {}
                  struct.idx = tonumber(s[2])
                  r.struct = struct
            elseif s[1] == TextPaser.facePrefix and s[2] then
                  r.type = TextPaser.msgType.face
                  local struct = {}
                  struct.idx = tonumber(s[2])
                  r.struct = struct
            elseif s[1] == TextPaser.wordPrefix and s[2] then

                  r.type = TextPaser.msgType.word
                  local struct = {}
                  local colorIdx = s[2] or 1
                  struct.color = Constants["color" .. colorIdx] or Constants.color6
                  struct.text =  s[3] or ""
                  r.struct = struct
            else
                  r.type = TextPaser.msgType.word
                  local struct = {}
                  struct.color = Constants.color6
                  struct.text =  v or ""
                  r.struct = struct
            end
            if r.type then 
                  table.insert(result, r)
            end
      end

      return result  
      --因为是通过玩家输入得到的字串 并不可靠 这个函数内部已经做了检测 通过这个函数得到的result可用 无需额外判断
end



return TextPaser
